<template>
    <div class="AI-dialog" v-if="contextLength && (codeHelp || isHGKJteam)">
        <div @click="AIHelp" class="AI-btn">
            <el-image :src="robotPng" class="robot-cion"> </el-image>
            <span> 代码协助 </span>
        </div>
        <el-dialog v-if="AICodeHelpDialogVisible" v-model="AICodeHelpDialogVisible" width="60%" append-to=".ojSass"
            draggable overflow>
            <template #header>
                <span class="icon-text el-dialog__header-title">
                    <el-icon class="text-primary">
                        <Guide />
                    </el-icon>
                    代码协助(AI)-{{ question?.name }}
                </span>
            </template>
            <div>
                <div>
                    <!-- :loading="isFirstRequestLoading || isSecondRequestLoading" -->
                    <el-button :loading="status === 'submitted' || status === 'streaming'" class="AI-start-btn" size=""
                        type="" plain @click="handleSubmit">
                        <el-image :src="robotPng" class="robot-cion"> </el-image>
                        <span style="display: inline-block;margin-left: 8px;"> 代码协助 </span>
                    </el-button>
                    <el-text type="primary" class="ai-idea-tips"> 以下内容为AI生成，仅供参考 </el-text>
                </div>
                <div class="" v-if="messages.length">
                    <div class="chat-messages" ref="messagesContainer">
                        <div v-for="(msg, index) in messages" :key="index" class="message" :class="msg.role">
                            <div class="message-content">
                                <div v-if="msg.role === 'assistant'" v-html="formatAIResponse(msg.content)" />
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </el-dialog>
    </div>
</template>

<script lang="ts" setup>
import { useChat } from '@ai-sdk/vue';
import { ElMessage } from 'element-plus';
import { marked } from 'marked';
import { v4 } from 'uuid';
import { computed, nextTick, onUnmounted, ref, toRefs, watch } from 'vue';
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
import { Storekey } from '../../../../interface';
import Studycodemodel from '../../../../mysql_interface/studycodemodel';
import { adminTeamId } from '../../../../util/data';
import robotPng from '../../../img/儿童机器人-01.png';
// import AIBtnPng from '../../../img/飞机.png';

// 常量定义
const MIN_CONTENT_LENGTH = 20;
const MIN_SIMILARITY_PERCENT = 50;
const p = defineProps<{
    ID?: number,
    user: Studycodemodel.Iuser,
    question?: Studycodemodel.Iquestion,
    context: string, language: string,
}>()
const { ID, question, context, language } = toRefs(p);
const router = useRouter()
const store = useStore(Storekey)
const user = computed(() => store.state.user);
const isAdmin = computed(() => {
    return user.value?.isAdmin
})
const getteam = computed(() => { return store.state.team?.rows || [] })
const isHGKJteam = computed(() => user.value?.teamid === adminTeamId)
const codeHelp = computed(() => { return getteam.value.some(c => c?.other?.codeHelp) })
const contextLength = computed(() => { return question.value?.context?.length || 0 >= MIN_CONTENT_LENGTH })

// 新增状态管理
const currentRequestId = ref<string>('');
const shouldContinueSecondRequest = ref(false);
const isFirstRequestLoading = ref(false);
const isSecondRequestLoading = ref(false);
const AICodeHelpDialogVisible = ref(false);
const messagesContainer = ref<HTMLElement>();

function getCookie(name: string) {
    const value = `; ${document.cookie}`
    const parts = value.split(`; ${name}=`)
    if (parts.length === 2) return parts.pop()?.split(';').shift()
    return null
}

const headers = computed(() => ({
    'x-csrf-token': getCookie('csrfToken') || '',
    'Content-Type': 'application/json'
}))

const {
    setMessages, messages, input,
    handleSubmit: originalHandleSubmit,
    status,
    stop,
    data: responseData
} = useChat({
    api: 'api/studycode/v1/user/chat/completions',
    headers: headers.value,
    streamProtocol: "data",
    body: {
        questionid: ID.value,
        userid: user.value?.ID,
        code: context.value,
        uuid: v4(),
        next: false
    },
    onFinish: (message) => {
        // 如果不是当前有效请求则忽略
        if (!currentRequestId.value) return;
        const content = message.content;
        // 使用正则表达式提取内容中的百分比数字
        const percentageMatch = content.match(/(\d+)%/);
        const percentage = percentageMatch ? parseInt(percentageMatch[1]) : 0;
        if (shouldContinueSecondRequest.value) {
            if (percentage >= MIN_SIMILARITY_PERCENT) {
                // 标记准备发送第二次请求
                shouldContinueSecondRequest.value = true;
                isFirstRequestLoading.value = false;
                isSecondRequestLoading.value = true;
                // 使用 setTimeout 让UI有时间更新
                setTimeout(() => {
                    if (shouldContinueSecondRequest.value) {
                        sendAIRequest(true); // 显式发起第二次请求
                    }
                }, 100);
            } else {
                ElMessage.warning(`代码与题目的关联度仅为${percentage}%，未达到要求`);
                isFirstRequestLoading.value = false;
            }
        }
    },
    onError: (error) => {
        if (error.name === 'AbortError') return;
        ElMessage.error(`请求错误: ${error.message}`);
        clear(false);
    }
})

// 完全重置方法
function clear(completeReset = true) {
    stop(); // 取消当前正在进行的任何请求

    // 使之前的回调无效
    currentRequestId.value = '';
    shouldContinueSecondRequest.value = false;
    isFirstRequestLoading.value = false;
    isSecondRequestLoading.value = false;

    if (completeReset) {
        setMessages([]);
        input.value = '';
    }
}

// 统一请求方法
async function sendAIRequest(isSecondRequest: boolean) {
    const requestId = Date.now().toString();
    currentRequestId.value = requestId;

    try {
        await originalHandleSubmit(new Event('submit'), {
            allowEmptySubmit: true,
            body: {
                questionid: ID.value,
                code: `${language.value == 'Python' ? '#' : '//'}这是第0行\r\n${context.value}`,
                userid: user.value?.ID,
                next: isSecondRequest
            },
        });

        // 检查是否仍然是当前有效请求
        if (currentRequestId.value !== requestId) return;

        scrollToBottom();
    } catch (error) {
        if (currentRequestId.value !== requestId) return;
        if ((error as Error).name !== 'AbortError') {
            ElMessage.error('请求失败: ' + (error as Error).message);
        }
    } finally {
        if (currentRequestId.value === requestId) {
            isFirstRequestLoading.value = false;
            isSecondRequestLoading.value = false;
        }
    }
}

// 修改后的 handleSubmit
const handleSubmit = async (e: Event) => {
    clear(false); // 不完全重置，保留消息
    isFirstRequestLoading.value = true;
    shouldContinueSecondRequest.value = true;
    await sendAIRequest(false);
};

async function AIHelp() {
    if (!context.value || context.value?.length < MIN_CONTENT_LENGTH) {
        ElMessage.error("代码内容太少");
        return;
    }
    AICodeHelpDialogVisible.value = true
}

const scrollToBottom = () => {
    if (messagesContainer.value) {
        nextTick(() => {
            messagesContainer.value?.scrollTo({
                top: messagesContainer.value.scrollHeight,
                behavior: 'smooth'
            })
        })
    }
}

const formatAIResponse = (content: string): string => {
    let formatted = content
        .replace(/^```markdown\n/, '')
        .replace(/```\s*$/, '');

    if ((formatted.match(/```/g) || []).length % 2 !== 0) {
        formatted += '\n```'
    }

    const cleanContent = formatted
        .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
        .replace(/on\w+="[^"]*"/g, '');

    marked.setOptions({
        breaks: true,
        gfm: true
    });

    return marked.parse(cleanContent || '');
};

// 组件卸载时清理
onUnmounted(() => {
    clear();
});

// 题目切换时完全重置
watch(() => ID.value, () => {
    clear();
    AICodeHelpDialogVisible.value = false;
});
</script>

<style scoped>
/* 保持原有的样式不变 */
.AI-dialog {
    --discuss-padding: 16px;
    display: block;
    width: 90px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center
}

.AI-btn {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-evenly;
}

.robot-cion {
    width: 26px;
}

.AI-start-btn {
    height: 36px;
    border-radius: 4px;
    margin-bottom: 10px;
    margin-right: 10px;
}

.ai-idea-tips {
    padding: calc(var(--discuss-padding) / 2) var(--discuss-padding);
    text-align: center;
    margin: 10px 0;
}

.chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: 12px;
    border: 1px solid var(--el-border-color);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    max-height: 60vh;
    position: relative;
}

.message.assistant .message-content {
    padding: 4px 10px;
    border-radius: 8px;
}

/* Markdown样式 */
.message-content :deep(h1) {
    font-size: 20px;
    font-weight: 600;
    margin: 16px 0 8px;
}

.message-content :deep(h2) {
    font-size: 18px !important;
    font-weight: 600;
    margin: 14px 0 8px;
}

.message-content :deep(h3) {
    font-size: 16px !important;
    font-weight: 600;
    margin: 12px 0 8px;
    padding-bottom: 4px;
}

.message-content :deep(h4) {
    font-size: 15px !important;
}

.message-content :deep(h5) {
    font-size: 15px !important;
}

.message-content :deep(p) {
    margin: 8px 0;
    line-height: 1.6;
}

.message-content :deep(ul) {
    margin: 8px 0;
    padding-left: 24px;
}

.message-content :deep(li) {
    margin: 6px 0;
    line-height: 1.6;
}

.message-content :deep(.inline-code) {
    font-family: 'Courier New', monospace;
    background: #f5f7fa;
    padding: 2px 4px;
    border-radius: 4px;
    color: #e96900;
}

.message-content :deep(pre) {
    background-color: #f6f8fa;
    padding: 1em;
    border-radius: 6px;
    overflow-x: auto;
    margin: 1em 0;
}

.message-content :deep(code) {
    font-family: 'Courier New', monospace;
    background-color: #f6f8fa;
    padding: 0.2em 0.4em;
    border-radius: 3px;
    color: #606266;
}

.message-content :deep(blockquote) {
    border-left: 4px solid #409EFF;
    padding: 0.5em 1em;
    margin: 1em 0;
    background-color: #f5f7fa;
    color: #606266;
}
</style>
<!-- <template>
    <div class="AI-dialog" v-if="contextLength && (codeHelp || isHGKJteam)">
        <div @click="AIHelp" class="AI-btn">
            <el-image :src="robotPng" class="robot-cion"> </el-image>
            <span> 代码协助 </span>
        </div>
        <el-dialog v-if="AICodeHelpDialogVisible" v-model="AICodeHelpDialogVisible" width="60%" append-to=".ojSass"
            draggable overflow>
            <template #header>
                <span class="icon-text el-dialog__header-title">
                    <el-icon class="text-primary">
                        <Guide />
                    </el-icon>
                    代码协助(AI)-{{ question?.name }}
                </span>
            </template>
            <div>
                <div>
                    <el-button :loading="isFirstRequestLoading || isSecondRequestLoading" class="AI-start-btn" size=""
                        type="" plain @click="handleSubmit">
                        <el-image :src="AIBtnPng" class="robot-cion"> </el-image>
                        <span style="display: inline-block;margin-left: 8px;"> 代码协助 </span>
                    </el-button>
                    <el-text type="primary" class="ai-idea-tips"> 以下内容为AI生成，仅供参考 </el-text>
                </div>
                <div class="" v-if="messages.length">
                    <div class="chat-messages" ref="messagesContainer">
                        <div v-for="(msg, index) in messages" :key="index" class="message" :class="msg.role">
                            <div class="message-content">
                                <div v-if="msg.role === 'assistant'" v-html="formatAIResponse(msg.content)" />
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </el-dialog>
    </div>
</template>

<script lang="ts" setup>
import { useChat } from '@ai-sdk/vue';
import { ElMessage } from 'element-plus';
import { marked } from 'marked';
import { v4 } from 'uuid';
import { computed, nextTick, onMounted, onUnmounted, ref, toRefs, watch } from 'vue';
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
import { Storekey } from '../../../../interface';
import Studycodemodel from '../../../../mysql_interface/studycodemodel';
import { adminTeamId } from '../../../../util/data';
import robotPng from '../../../img/儿童机器人-01.png';
import AIBtnPng from '../../../img/飞机.png';

const contextLimit = 20
const p = defineProps<{
    ID?: number,
    user: Studycodemodel.Iuser,
    question?: Studycodemodel.Iquestion,
    context: string, language: string,
}>()
const { ID, question, context, language } = toRefs(p);
const router = useRouter()
const store = useStore(Storekey)
const user = computed(() => store.state.user);
const isAdmin = computed(() => {
    return user.value?.isAdmin
})
const getteam = computed(() => { return store.state.team?.rows || [] })
const isHGKJteam = computed(() => user.value?.teamid === adminTeamId)
const codeHelp = computed(() => { return getteam.value.some(c => c?.other?.codeHelp) })
const contextLength = computed(() => { return question.value?.context?.length || 0 >= contextLimit })

// 新增状态管理
const currentRequestId = ref<string>('');
const shouldContinueSecondRequest = ref(false);
const isFirstRequestLoading = ref(false);
const isSecondRequestLoading = ref(false);
const AICodeHelpDialogVisible = ref(false);
const messagesContainer = ref<HTMLElement>();

function getCookie(name: string) {
    const value = `; ${document.cookie}`
    const parts = value.split(`; ${name}=`)
    if (parts.length === 2) return parts.pop()?.split(';').shift()
    return null
}

const headers = computed(() => ({
    'x-csrf-token': getCookie('csrfToken') || '',
    'Content-Type': 'application/json'
}))

const {
    setMessages, messages, input,
    handleSubmit: originalHandleSubmit,
    status,
    stop,
    data: responseData
} = useChat({
    api: 'api/studycode/v1/user/chat/completions',
    headers: headers.value,
    streamProtocol: "data",
    body: {
        questionid: ID.value,
        userid: user.value?.ID,
        code: context.value,
        uuid: v4(),
        next: false
    },
    onFinish: (message) => {
        // 如果不是当前有效请求则忽略
        if (!currentRequestId.value) return;
        
        const content = message.content;
        
        if (shouldContinueSecondRequest.value) {
            if (content.includes("不通过")) {
                ElMessage.warning("代码关联度检查未通过");
                isFirstRequestLoading.value = false;
            } else if (content.includes("通过")) {
                // 标记准备发送第二次请求
                shouldContinueSecondRequest.value = true;
                isFirstRequestLoading.value = false;
                isSecondRequestLoading.value = true;
                
                // 使用 setTimeout 让UI有时间更新
                setTimeout(() => {
                    if (shouldContinueSecondRequest.value) {
                        sendAIRequest(true); // 显式发起第二次请求
                    }
                }, 100);
            }
        }
    },
    onError: (error) => {
        if (error.name === 'AbortError') return;
        ElMessage.error(`请求错误: ${error.message}`);
        clear(false);
    }
})

// 完全重置方法
function clear(completeReset = true) {
    stop(); // 取消当前正在进行的任何请求
    
    // 使之前的回调无效
    currentRequestId.value = '';
    shouldContinueSecondRequest.value = false;
    isFirstRequestLoading.value = false;
    isSecondRequestLoading.value = false;
    
    if (completeReset) {
        setMessages([]);
        input.value = '';
    }
}

// 统一请求方法
async function sendAIRequest(isSecondRequest: boolean) {
    const requestId = Date.now().toString();
    currentRequestId.value = requestId;
    
    try {
        await originalHandleSubmit(new Event('submit'), {
            allowEmptySubmit: true,
            body: {
                questionid: ID.value,
                code: `${language.value == 'Python' ? '#' : '//'}这是第0行\r\n${context.value}`,
                userid: user.value?.ID,
                next: isSecondRequest
            },
        });
        
        // 检查是否仍然是当前有效请求
        if (currentRequestId.value !== requestId) return;
        
        scrollToBottom();
    } catch (error) {
        if (currentRequestId.value !== requestId) return;
        if ((error as Error).name !== 'AbortError') {
            ElMessage.error('请求失败: ' + (error as Error).message);
        }
    } finally {
        if (currentRequestId.value === requestId) {
            isFirstRequestLoading.value = false;
            isSecondRequestLoading.value = false;
        }
    }
}

// 修改后的 handleSubmit
const handleSubmit = async (e: Event) => {
    clear(false); // 不完全重置，保留消息
    isFirstRequestLoading.value = true;
    shouldContinueSecondRequest.value = true;
    await sendAIRequest(false);
};

async function AIHelp() {
    if (!context.value || context.value?.length < contextLimit) {
        ElMessage.error("代码内容太少");
        return;
    }
    AICodeHelpDialogVisible.value = true
}

const scrollToBottom = () => {
    if (messagesContainer.value) {
        nextTick(() => {
            messagesContainer.value?.scrollTo({
                top: messagesContainer.value.scrollHeight,
                behavior: 'smooth'
            })
        })
    }
}

const formatAIResponse = (content: string): string => {
    let formatted = content
        .replace(/^```markdown\n/, '')
        .replace(/```\s*$/, '');

    if ((formatted.match(/```/g) || []).length % 2 !== 0) {
        formatted += '\n```'
    }

    const cleanContent = formatted
        .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
        .replace(/on\w+="[^"]*"/g, '');

    marked.setOptions({
        breaks: true,
        gfm: true
    });

    return marked.parse(cleanContent || '');
};

// 组件卸载时清理
onUnmounted(() => {
    clear();
});

// 题目切换时完全重置
watch(() => ID.value, () => {
    clear();
    AICodeHelpDialogVisible.value = false;
    nextTick(() => {
        AICodeHelpDialogVisible.value = true;
    });
});
</script>

<style scoped>
/* 保持原有的样式不变 */
.AI-dialog {
    --discuss-padding: 16px;
    display: block;
    width: 90px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center
}

.AI-btn {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-evenly;
}

.robot-cion {
    width: 26px;
}

.AI-start-btn {
    height: 36px;
    border-radius: 4px;
    margin-bottom: 10px;
    margin-right: 10px;
}

.ai-idea-tips {
    padding: calc(var(--discuss-padding) / 2) var(--discuss-padding);
    text-align: center;
    margin: 10px 0;
}

.chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: 12px;
    border: 1px solid var(--el-border-color);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    max-height: 60vh;
    position: relative;
}

.message.assistant .message-content {
    padding: 4px 10px;
    border-radius: 8px;
}

/* Markdown样式 */
.message-content :deep(h1) {
    font-size: 20px;
    font-weight: 600;
    margin: 16px 0 8px;
}

.message-content :deep(h2) {
    font-size: 18px !important;
    font-weight: 600;
    margin: 14px 0 8px;
}

.message-content :deep(h3) {
    font-size: 16px !important;
    font-weight: 600;
    margin: 12px 0 8px;
    padding-bottom: 4px;
}

.message-content :deep(h4) {
    font-size: 15px !important;
}

.message-content :deep(h5) {
    font-size: 15px !important;
}

.message-content :deep(p) {
    margin: 8px 0;
    line-height: 1.6;
}

.message-content :deep(ul) {
    margin: 8px 0;
    padding-left: 24px;
}

.message-content :deep(li) {
    margin: 6px 0;
    line-height: 1.6;
}

.message-content :deep(.inline-code) {
    font-family: 'Courier New', monospace;
    background: #f5f7fa;
    padding: 2px 4px;
    border-radius: 4px;
    color: #e96900;
}

.message-content :deep(pre) {
    background-color: #f6f8fa;
    padding: 1em;
    border-radius: 6px;
    overflow-x: auto;
    margin: 1em 0;
}

.message-content :deep(code) {
    font-family: 'Courier New', monospace;
    background-color: #f6f8fa;
    padding: 0.2em 0.4em;
    border-radius: 3px;
    color: #606266;
}

.message-content :deep(blockquote) {
    border-left: 4px solid #409EFF;
    padding: 0.5em 1em;
    margin: 1em 0;
    background-color: #f5f7fa;
    color: #606266;
}
</style> -->